package cn.js189.uqc.util;

import cn.js189.uqc.redis.RedisOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RedisUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(RedisUtil.class);


	/**
	 * redis set成功返回标识
	 */
	public static final String LOCK_SUCCESS = "OK";

	public static final int RETRY = 5;

	/**
	 * redis key失效时间
	 */
	private static final long EXPIRE_TIME = 60000L;

	private RedisUtil() {
		throw new IllegalStateException("Utility class");
	}


	public static String tryLock(RedisOperation redisOperation, String optName, final String lockKey, final String lockValue) {
		LOGGER.info("[{}] 获取锁 Key:{} Value:{}", optName, lockKey, lockValue);
		String result = "";

		try {

			result = redisOperation.set(lockKey, lockValue, "NX", "PX", EXPIRE_TIME);
			LOGGER.info("[{}] Key:{} Value:{} 获取锁结果: {}", optName, lockKey, lockValue, result);

		} catch (Exception e) {
			LOGGER.info("[{}] 获取锁 Key:{} Value:{} 异常!{}", optName, lockKey, lockValue, e.getMessage());
		}

		return result;
	}

	public static void unlock(RedisOperation redisOperation, String optName, String lockKey, String lockValue) {
		LOGGER.info("[{}] 释放锁 Key:{} Value:{}", optName, lockKey, lockValue);
		try {

			String result = redisOperation.getForString(lockKey);

			LOGGER.info("[{}] 释放锁 Key:{} Value:{} LockValue:{}", optName, lockKey, lockValue, result);

			if (StringUtils.equals(result, lockValue)) {
				redisOperation.del(lockKey);
				LOGGER.info("[{}] 释放锁成功! Key:{}", optName, lockKey);
			}

		} catch (Exception e) {
			LOGGER.info("[{}] 释放锁 Key:{} Value:{} 异常!{}", optName, lockKey, lockValue, e.getMessage());
		}

	}

	public static String waitForTryLock(RedisOperation redisOperation, String optName, final String lockKey, final String lockValue) {
		LOGGER.info("[{}] 获取锁 Key:{} Value:{}", optName, lockKey, lockValue);
		String result = "";

		try {

			int retry = 0;

			do {

				LOGGER.info("[{}] TRY LOCK RETRY:{}", optName, retry);

				result = redisOperation.set(lockKey, lockValue, "NX", "PX", EXPIRE_TIME);

				LOGGER.info("[{}] Key:{} Value:{} 获取锁结果: {}", optName, lockKey, lockValue, result);

				if (StringUtils.equals(LOCK_SUCCESS, result)) {
					break;
				}

				retry++;

				Thread.sleep(1000);

			} while (retry <= RETRY);


		} catch (Exception e) {
			LOGGER.info("[{}] 获取锁 Key:{} Value:{} 异常!{}", optName, lockKey, lockValue, e.getMessage());
			Thread.currentThread().interrupt();
		}

		return result;
	}

}
